/*
 * mem.c
 *
 * Implements memory apis
 *
 * Edited by: krishna
 */

#include "mem.h"
/* ----------------------------------------------------------------------- 
 * prints the number of free variables for debug purposes
 * ----------------------------------------------------------------------- 
 */
int number_free_registers() {
	int count = 0;
	int i = 0;
	for (i=0; i<VAR_COUNT; i++) {
		if (temp_variables[i].inuse == 0) count++;
	}
	return count;
}


/* ----------------------------------------------------------------------- 
 * inits the tmp variables to name to,t1...t9 for mips
 * ----------------------------------------------------------------------- 
 */
void init_tmp_variables ()
    {
    int i=0;
    for (i=0; i<VAR_COUNT; i++)
        {
        temp_variables[i].inuse = 0;
        strcpy(temp_variables[i].name, "$t");
        strcat(temp_variables[i].name, inttostring(i));
        }
    }

/* ----------------------------------------------------------------------- 
 * Pops the first available(unused) tmp variable (to is the first)
 * ----------------------------------------------------------------------- 
 */
struct temp_variables_t * pop_tmp_variable (char * var, int containsAddressFlag)
    {
    int i=0;
    /* this function can be made smarter with single loop 
     * But doing the following way for simplicity */

    /* first loop for checking if var_inuse is already inuse.
     * If so, return the corresponding temp register */
    for (i=0; i<VAR_COUNT; i++)
        {
        if (temp_variables[i].inuse == 1)
            {
            if (!strcmp(temp_variables[i].var_inuse, var))
                return &temp_variables[i];
            }
        }

    for (i=0; i<VAR_COUNT; i++)
        {
        if (temp_variables[i].inuse == 0)
            {
            memset (temp_variables[i].var_inuse, 0 , 
                    sizeof (temp_variables[i].var_inuse));
            strcpy(temp_variables[i].var_inuse, var);
            temp_variables[i].contains_address_flag = containsAddressFlag;
            temp_variables[i].inuse = 1;
            return &temp_variables[i];
            }
        }
    return NULL;
    }

/* ----------------------------------------------------------------------- 
 * Pushes the used tmp variable. This will available for using again
 * ----------------------------------------------------------------------- 
 */
void push_tmp_variable (char * name)
    {
    int i=0;
    for (i=0; i<VAR_COUNT; i++)
        {
        if (!strcmp(temp_variables[i].name, name))
            {
            memset(temp_variables[i].var_inuse, 0 , 
                   sizeof (temp_variables[i].var_inuse));
            temp_variables[i].inuse = 0;
            }
        }
    }

/* ----------------------------------------------------------------------- 
 * Prints the all the temp variables and their inUse flag
 * ----------------------------------------------------------------------- 
 */
void print_tmp_variables()
    {
    int i=0;
        printf("================TMP VARIABLES==============\n");
    for (i=0; i<VAR_COUNT; i++)
        {
        printf("variable is %s \t inuse = %d \t by = %s \t type =%s\n", 
               temp_variables[i].name, temp_variables[i].inuse,
               temp_variables[i].var_inuse, temp_variables[i].type_name);
        }
        printf("===========================================\n");
    }
